﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using ExpressionType = Gear.ToolKits.Base.PageFactor.ExpressionType;

namespace Gear.ToolKits.Extensions
{
    /// <summary>
    /// 动态Lambda构造类
    /// </summary>
    /// <typeparam name="Dto"></typeparam>
    public class LambdaExtention<Dto> where Dto : class
    {
        private List<Expression> m_lstExpression = null;
        private ParameterExpression m_Parameter = null;

        public LambdaExtention()
        {
            m_lstExpression = new List<Expression>();
            m_Parameter = Expression.Parameter(typeof(Dto), "x");
        }

        //构造表达式，存放到m_lstExpression集合里面
        public void GetExpression(string strPropertyName, object strValue, ExpressionType expressType)
        {
            try
            {
                Expression expRes = null;
                MemberExpression member = Expression.PropertyOrField(m_Parameter, strPropertyName);
                if (member.Type == typeof(int?) || member.Type == typeof(int))
                {
                    strValue = Convert.ToInt32(strValue);
                }
                else if (member.Type == typeof(DateTime?) || member.Type == typeof(DateTime))
                {
                    strValue = Convert.ToDateTime(strValue);
                }


                if (expressType == ExpressionType.Contains)
                {
                    expRes = Expression.Call(member, typeof(string).GetMethod("Contains", new Type[] { typeof(string) }), Expression.Constant(strValue.ToString()));

                }
                else if (expressType == ExpressionType.Equal)
                {
                    expRes = Expression.Equal(member, Expression.Constant(strValue, member.Type));
                }
                else if (expressType == ExpressionType.LessThan)
                {
                    expRes = Expression.LessThan(member, Expression.Constant(strValue, member.Type));
                }
                else if (expressType == ExpressionType.LessThanOrEqual)
                {
                    expRes = Expression.LessThanOrEqual(member, Expression.Constant(strValue, member.Type));
                }
                else if (expressType == ExpressionType.GreaterThan)
                {
                    expRes = Expression.GreaterThan(member, Expression.Constant(strValue, member.Type));
                }
                else if (expressType == ExpressionType.GreaterThanOrEqual)
                {
                    expRes = Expression.GreaterThanOrEqual(member, Expression.Constant(strValue, member.Type));
                }
                //return expRes;
                m_lstExpression.Add(expRes);
            }
            catch (Exception e)
            {
                throw;
            }

        }


        //得到Lamada表达式的Expression对象
        public Expression<Func<Dto, bool>> GetLambda()
        {
            Expression whereExpr = null;
            foreach (var expr in m_lstExpression)
            {
                if (whereExpr == null) whereExpr = expr;
                else whereExpr = Expression.And(whereExpr, expr);
            }
            if (whereExpr == null)
                return null;
            return Expression.Lambda<Func<Dto, bool>>(whereExpr, m_Parameter);
        }


    }
}
